﻿using AIVision.Inspect.Halcon;
using AIVision.Inspect.HCDL;
using AIVision.Inspect.Toolkit;
using AIVision.Model;
using AIVision.Model.EntityModels;
using AIVision.Model.Events;
using AIVision.Model.InspectModels;
using AIVision.Repository.Entitys;
using HalconDotNet;
using Prism.Events;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using XRVision.BaseCheckUnit;
using XRVision.DLCheckUnit;

namespace AIVision.Inspect
{
    public class CheckStationAgent: BindableBase
    {
        public string SampleCode { get; set; }

        private CheckStationDto checkStationCfg;
        public CheckStationDto CheckStationCfg { get => checkStationCfg; set => checkStationCfg = value; }
        
        private IEventAggregator eventAggregator;

  
        private MyBaseCamera Camera;
       
        public HObject CurrentImage { get => currentImage; set => currentImage = value; }
        private HObject currentImage;

        public InspectResultModel FinalCheckUnitResult { get => finalCheckUnitResult; set => finalCheckUnitResult = value; }
        private InspectResultModel finalCheckUnitResult;

        public ICheckUnit checkUnit;

        public CheckStationAgent(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
        }

        public void Init(CheckStationDto stationCfg)
        {
            this.checkStationCfg = stationCfg;
            //初始化相机
            if (checkStationCfg.StationType == EnumStationType.Camera.ToString())
            {
                OpenCamera();
                InitCheckUnit();
            }

        }
        public void OpenCamera()
        {
            try
            {
                Camera = new HKCamerSDK();//根据我们需要开启的相机品牌去实例化化相机类
                Camera.CamerName = checkStationCfg.Camera.Name;
                var list = Camera.FindCamer();
                var v = Camera.OpenCamer(checkStationCfg.Camera.HardKey);
                if (!v)
                {
                    throw new Exception($"相机{Camera.CamerName}打开失败");
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"相机{Camera.CamerName}打开失败");
            }
        }

        private void CloseCamera()
        {
            Camera.CloseCamer();
        }
        //一个工位只使用一个模型，通过模型进行多次图像判定
        public void InitCheckUnit()
        {
            if (checkStationCfg.InspectType == EnumInspectType.DL.ToString())
            {
                //判断hc文件是否存在
                if (!File.Exists(checkStationCfg.HCFilePath))
                {
                    throw new Exception("HC脚本文件不存在");
                }
                //如果是dl，判断process和model文件是否存在
                HTuple gpn = new HTuple(), gpv = new HTuple();
                gpn.Append("runtime");
                gpn.Append("runtime");
                gpv.Append("cpu");
                gpv.Append("gpu");
                HTuple DLDeviceHandles;
                HOperatorSet.QueryAvailableDlDevices(gpn, gpv, out DLDeviceHandles);
                if (!File.Exists(checkStationCfg.DLProcessFilePath))
                {
                    throw new Exception("深度学习Process文件不存在");
                }
                if (!File.Exists(checkStationCfg.DLModelFilePath))
                {
                    throw new Exception("深度学习Model文件不存在");
                }

                checkUnit = new DLCheckUnitInstance();
                if (checkStationCfg.DLDevice.ToUpper() == "CPU")
                    checkUnit.Init(checkStationCfg.HCFilePath, checkStationCfg.DLProcessFilePath, checkStationCfg.DLModelFilePath, DLDeviceHandles[0], checkStationCfg.DefectItems, checkStationCfg.OKScore);
                else if (checkStationCfg.DLDevice.ToUpper() == "GPU")
                    checkUnit.Init(checkStationCfg.HCFilePath, checkStationCfg.DLProcessFilePath, checkStationCfg.DLModelFilePath, DLDeviceHandles[1], checkStationCfg.DefectItems, checkStationCfg.OKScore);
            }
            else if(checkStationCfg.InspectType == EnumInspectType.Base.ToString())
            {
                //判断hc文件是否存在
                if (!File.Exists(checkStationCfg.HCFilePath))
                {
                    throw new Exception("HC脚本文件不存在");
                }
                checkUnit = new BaseCheckUnitInstance();
                checkUnit.Init(checkStationCfg.HCFilePath, checkStationCfg.DefectItems, checkStationCfg.OKScore);
            }
            else if (checkStationCfg.InspectType == EnumInspectType.OBJ.ToString())
            {
                //判断hc文件是否存在
                if (!File.Exists(checkStationCfg.HCFilePath))
                {
                    throw new Exception("HC脚本文件不存在");
                }
                //如果是dl，判断process和model文件是否存在
                HTuple gpn = new HTuple(), gpv = new HTuple();
                gpn.Append("runtime");
                gpn.Append("runtime");
                gpv.Append("cpu");
                gpv.Append("gpu");
                HTuple DLDeviceHandles;
                HOperatorSet.QueryAvailableDlDevices(gpn, gpv, out DLDeviceHandles);
                if (!File.Exists(checkStationCfg.DLProcessFilePath))
                {
                    throw new Exception("深度学习Process文件不存在");
                }
                if (!File.Exists(checkStationCfg.DLModelFilePath))
                {
                    throw new Exception("深度学习Model文件不存在");
                }

                checkUnit = new DLObjCheckUnitInstance();
                if (checkStationCfg.DLDevice.ToUpper() == "CPU")
                    checkUnit.Init(checkStationCfg.HCFilePath, checkStationCfg.DLProcessFilePath, checkStationCfg.DLModelFilePath, DLDeviceHandles[0], checkStationCfg.DefectItems, checkStationCfg.OKScore);
                else if (checkStationCfg.DLDevice.ToUpper() == "GPU")
                    checkUnit.Init(checkStationCfg.HCFilePath, checkStationCfg.DLProcessFilePath, checkStationCfg.DLModelFilePath, DLDeviceHandles[1], checkStationCfg.DefectItems, checkStationCfg.OKScore);
            }
            else
            {
                throw new Exception($"工位{checkStationCfg.StationCode}检测模型初始化错误");
            }
        }
        public void GetImage()
        {
            try
            {
                if (currentImage != null)
                {
                    currentImage.Dispose();
                    currentImage = null;
                }
                currentImage = Camera.OneGrap();
                if(currentImage == null)
                    throw new Exception($"获取图像为空");
            }
            catch (Exception ex)
            {
                throw new Exception($"获取图像失败:{ex.Message}");
            }
           
        }

        public void ExInspect(SampleDataModel sampleData)
        {

            //if(checkStationCfg.IsSaveOKImage)
            //{
            //    string savePath = Path.Combine(checkStationCfg.ImageFileSavePath, DateTime.Now.ToString("yyyyMMdd"));
            //    if (!Directory.Exists(savePath))
            //    {
            //        Directory.CreateDirectory(savePath);
            //    }
            //    string fileName = Path.Combine(savePath, DateTime.Now.ToString("HHmmssfff") + ".bmp");
            //    HOperatorSet.WriteImage(currentImage, "bmp", 0, fileName);
            
            //}

            finalCheckUnitResult = checkUnit.ExUnitCheck(currentImage);


            ShowImageModel showImage = new ShowImageModel()
            {
                SourceImage = currentImage,
                InspectImage = finalCheckUnitResult.InspectImage,
                HSmartWindowName = checkStationCfg.HSmartWindowName,
                Score = finalCheckUnitResult.Score,
                Defects = finalCheckUnitResult.Defects,
                Location = sampleData.Location
            };
            eventAggregator.GetEvent<ShowImageEvent>().Publish(showImage);
            //if (currentImage != null)
            //{
            //    currentImage.Dispose();
            //    currentImage = null;
            //}
        }
    }
}
